package com.mall.common.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.mall.common.dao.ComponentDao;
import com.mall.common.domain.component.ComponentBundleDomain;
import com.mall.common.domain.component.ComponentDomain;
import com.mall.common.exception.NoticeException;
import com.mall.common.hibernate.Finder;
import com.mall.common.plugin.IPlugin;
import com.mall.common.plugin.IPluginBundle;
import com.mall.common.service.ComponentService;
import com.mall.common.util.SpringUtils;

/**
 * Service实现类 - 插件
 */
@Service
@Transactional
public class ComponentServiceImpl extends BaseServiceImpl<ComponentDomain, Long> implements
	ComponentService {

	@Resource private ComponentDao componentDao;
	
	@Resource
	public void setBaseDao(ComponentDao componentDao) {
		super.setBaseDao(componentDao);
	}

	@Override
	@Transactional(readOnly=true)
	public ComponentDomain enableComponent(Long componentId) {
		return componentDao.findEnableComponent(componentId);		 
	}
	
	@Override
	@Transactional(readOnly=true)
	public List<ComponentDomain> queryComponentByBundleId(String bundleId) {
		String hql = "select c from ComponentDomain c,ComponentBundleDomain cb where c.componentBundle.id = cb.id and cb.bundleId = :bundleId";
		Finder finder = Finder.create(hql);
		finder.setParam("bundleId", bundleId);
		return finder.findHQLList();
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void install(Long id) {
		ComponentDomain component = this.find(id);
		if(component == null){
			throw new NoticeException("组件不存在!");
		}
		component.setInstallState("1");
		this.update(component);
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void unInstall(Long id) {
		ComponentDomain component = this.find(id);
		if(component == null){
			throw new NoticeException("组件不存在!");
		}
		component.setInstallState("2");
		this.update(component);
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	public void start(Long id) {
		ComponentDomain component = this.find(id);
		if(component == null){
			throw new NoticeException("组件不存在!");
		}
		IPlugin plug = (IPlugin) SpringUtils.getBean(component.getComponentId());
		ComponentBundleDomain bundle = component.getComponentBundle();
		if(plug != null && bundle != null){
			IPluginBundle pluginBundle = (IPluginBundle) SpringUtils.getBean(bundle.getBundleId());
			if(pluginBundle != null){
				pluginBundle.registerPlugin(plug);
			}
		}
		component.setEnableState("1");
		this.update(component);
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void stop(Long id) {
		ComponentDomain component = this.find(id);
		if(component == null){
			throw new NoticeException("组件不存在!");
		}
		IPlugin plug = (IPlugin) SpringUtils.getBean(component.getComponentId());
		ComponentBundleDomain bundle = component.getComponentBundle();
		if(plug != null && bundle != null){
			IPluginBundle pluginBundle = (IPluginBundle) SpringUtils.getBean(bundle.getBundleId());
			if(pluginBundle != null){
				pluginBundle.unRegisterPlugin(plug);
			}
		}
		component.setEnableState("2");
		this.update(component);
	}

	@Override
	@Transactional(readOnly=true)
	@Cacheable(value="component", key="'component'+#componentId")
	public ComponentDomain getComponent(String componentId) {
		String hql = "from ComponentDomain bean where bean.componentId = :componentId and bean.enableState='1'";
		Finder f = Finder.create(hql);
		f.setParam("componentId", componentId);
		return (ComponentDomain) f.findUniqueByHQL();
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public void persist(ComponentDomain entity) {
		super.persist(entity);
	}

	@Override
	@CacheEvict(value="component",allEntries=true)
	@Transactional(propagation=Propagation.REQUIRED)
	public ComponentDomain update(ComponentDomain entity) {
		return super.update(entity);
	}
	
}
